<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="U7lUi" id="U7lUi"><span data-lake-id="u2d90a8ee" id="u2d90a8ee">典型回答</span></h1>
  <p data-lake-id="u22213115" id="u22213115"><br></p>
  <p data-lake-id="u330c4e43" id="u330c4e43"><span data-lake-id="u6c169675" id="u6c169675">Innodb是MySQL的执行引擎，MySQL是一种关系型数据库，而Redis是一种非关系型数据库。这两者之间比较大的区别是：</span><span data-lake-id="ud04337e2" id="ud04337e2" class="lake-fontsize-12" style="color: rgb(36, 41, 47)">关系型数据库以表的形式进行存储数据，而非关系型数据库以Key-value的形式存储数据。 </span></p>
  <p data-lake-id="uc0f303f7" id="uc0f303f7"><span data-lake-id="ueb85b069" id="ueb85b069">​</span><br></p>
  <p data-lake-id="udc806ee9" id="udc806ee9"><span data-lake-id="u91c45315" id="u91c45315">MySQL是基于磁盘存储的，Redis是基于内存存储的。</span><strong><span data-lake-id="u2c13951c" id="u2c13951c">而B+树是一种磁盘IO友好型的数据结构，跳表则是一种内存友好型的数据结构。</span></strong></p>
  <p data-lake-id="uec25e7ac" id="uec25e7ac"><br></p>
  <p data-lake-id="ue37cedc7" id="ue37cedc7"><span data-lake-id="ub6c5e991" id="ub6c5e991">为什么说B+树是磁盘IO友好的呢？</span></p>
  <p data-lake-id="uc5d7940a" id="uc5d7940a"><span data-lake-id="u0db3b4d4" id="u0db3b4d4">​</span><br></p>
  <p data-lake-id="ub39878cc" id="ub39878cc"><span data-lake-id="u3d966c93" id="u3d966c93">首先，B+树的叶子节点形成有序链表，可以方便地进行范围查询操作。对于磁盘存储来说，顺序读取的效率要高于随机读取，因为它可以充分利用磁盘预读和缓存机制，减少磁盘 I/O 的次数。</span></p>
  <p data-lake-id="u2420f0c7" id="u2420f0c7"><span data-lake-id="u2e9f0848" id="u2e9f0848">​</span><br></p>
  <p data-lake-id="uc3014c40" id="uc3014c40"><span data-lake-id="uae0d573a" id="uae0d573a">其次，由于B+树的节点大小是固定的，因此可以很好地利用磁盘预读特性，一次性读取多个节点到内存中，这样可以减少IO操作次数，提高查询效率。</span></p>
  <p data-lake-id="u93904430" id="u93904430"><span data-lake-id="u09f62e32" id="u09f62e32">​</span><br></p>
  <p data-lake-id="u75737e57" id="u75737e57"><span data-lake-id="uad67a2f3" id="uad67a2f3">还有就是，B+树的叶子节点都存储数据，而非数据和指针混合，所以叶子节点的大小是固定的，而且节点的大小一般都会设置为一页的大小，这就使得节点分裂和合并时，IO操作很少，只需读取和写入一页。</span></p>
  <p data-lake-id="u7f1f40b3" id="u7f1f40b3"><span data-lake-id="ud5be904f" id="ud5be904f" class="lake-fontsize-12">​</span><br></p>
  <p data-lake-id="u5c0ec886" id="u5c0ec886"><br></p>
  <p data-lake-id="u6893efaf" id="u6893efaf"><span data-lake-id="u1dd8d5d5" id="u1dd8d5d5">所以，B+树在设计上考虑了磁盘存储的特点和性能优化，</span><span data-lake-id="u40998c3a" id="u40998c3a" class="lake-fontsize-12">我们曾经分析过，当Innodb中存储2000万数据的时候，只需要3次磁盘就够了。</span></p>
  <p data-lake-id="u414639fe" id="u414639fe"><br></p>
  <p data-lake-id="ud047f2d0" id="ud047f2d0"><br></p>
  <p data-lake-id="u657d15c4" id="u657d15c4"><span data-lake-id="u8ab056bd" id="u8ab056bd">而跳表就不一样了，跳表的索引节点通过跳跃指针连接，形成多级索引结构。这导致了跳表的索引节点在磁盘上存储时会出现数据分散的情况，即索引节点之间的物理距离可能较远。对于磁盘存储来说，随机访问分散的数据会增加磁头的寻道时间，导致磁盘 I/O 的性能下降。</span></p>
  <p data-lake-id="uce3a5ff2" id="uce3a5ff2"><span data-lake-id="u0b9b7a09" id="u0b9b7a09">​</span><br></p>
  <p data-lake-id="u9004832d" id="u9004832d"><span data-lake-id="u58f1ac6e" id="u58f1ac6e">那么，为啥Redis要用跳表实现ZSET呢（不只是跳表，详见下面链接）？而不是B+树呢？</span></p>
  <p data-lake-id="u27f9e1de" id="u27f9e1de"><span data-lake-id="u06235a66" id="u06235a66">​</span><br></p>
  <p data-lake-id="ud7cc2540" id="ud7cc2540"><br></p>
  <p data-lake-id="ue888e39a" id="ue888e39a"><span data-lake-id="uc565d592" id="uc565d592">因为Redis是一种基于内存的数据结构，他不需要考虑磁盘IO的性能问题，所以，他完全可以选择一个简单的数据结构，并且性能也能接受的 ，那么跳表就很合适，</span></p>
  <p data-lake-id="ua92edbb6" id="ua92edbb6"><span data-lake-id="u4e1081d1" id="u4e1081d1">​</span><br></p>
  <p data-lake-id="ub9d17fdc" id="ub9d17fdc"><span data-lake-id="u20a40f6f" id="u20a40f6f">因为跳表相对于B+树来说，更简单。相比之下，B+树作为一种复杂的索引结构，需要考虑节点分裂和合并等复杂操作，增加了实现和维护的复杂度。</span></p>
  <p data-lake-id="ua28c9f0b" id="ua28c9f0b"><span data-lake-id="u6f14b3ca" id="u6f14b3ca">​</span><br></p>
  <p data-lake-id="u18c41d61" id="u18c41d61"><span data-lake-id="u19f3e9f7" id="u19f3e9f7">而且，Redis的有序集合经常需要进行插入、删除和更新操作。跳表在动态性能方面具有良好的表现，特别是在插入和删除操作上。相比之下，B+树的插入和删除需要考虑平衡性，所以还是成本挺高的。</span></p>
 </body>
</html>